/************************************************************************
Author:			Trey Turley, Thomas Lee, Marc Willis

Filename:		TEd.cpp

Description:	Tron EDitor.  Edits custom stages for Tron.

Date Modified:	8/9/10
				- File created
*************************************************************************/

#include <iostream>
#include <fstream>
#include "Draw.h"
#include "keyboard.h"

#include <strsafe.h>

using namespace std;

const char CURSOR=79;

int dirToChar(int dir)
{
	if(dir==1)
	{
		return (int)LEFT;
	}
	if(dir==2)
	{
		return (int)UP;
	}
	if(dir==3)
	{
		return (int)RIGHT;
	}
	if(dir==4)
	{
		return (int)DOWN;
	}
	return CURSOR;
}

int playerColor(int player)
{
	if(player==1)
	{
		return blue;
	}
	if(player==2)
	{
		return red;
	}
	if(player==3)
	{
		return green;
	}
	if(player==4)
	{
		return yellow;
	}
	return cyan;
}

int main()
{
	ifstream infile;
	ofstream outfile;
	Plotter plot;
	bool running=true;
	bool inMenu;
	int map[80][40];
	int playerData[4][3];
	int selection;
	char *filename;
	int cursorX, cursorY;
	filename=new char[1000];
	
	// Old code
	//HWND console = GetConsoleWindow();
	//RECT r;
	//GetWindowRect(console, &r); //stores the console's current dimensions
	//MoveWindow(console, r.left, r.top, 800, 600, TRUE);
	
	HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo;
	COORD dwSize;

	if (!GetConsoleScreenBufferInfo(hConsoleOutput, &lpConsoleScreenBufferInfo) ) {
		cout << "failed to get handle";
		throw;
	}

	dwSize.Y = 48;
	dwSize.X = 80;

	if (!SetConsoleScreenBufferSize(hConsoleOutput, dwSize) )
	{
		cout << "failed to set console buffer";
		throw;
	}

	lpConsoleScreenBufferInfo.srWindow.Left = 0;
	lpConsoleScreenBufferInfo.srWindow.Top = 0;
	lpConsoleScreenBufferInfo.srWindow.Bottom = 47;
	lpConsoleScreenBufferInfo.srWindow.Right = 79;

	if (!SetConsoleWindowInfo(hConsoleOutput, TRUE, &lpConsoleScreenBufferInfo.srWindow ) )
	{
		cout << "failed to set console window size";
		throw;
	}
	TCHAR szOldTitle[MAX_PATH];
	TCHAR szNewTitle[MAX_PATH];

	if( GetConsoleTitle(szOldTitle, MAX_PATH) )
	{
		StringCchPrintf(szNewTitle, MAX_PATH, TEXT("                                                                               TRON LEVEL EDITOR"), szOldTitle);
		if( !SetConsoleTitle(szNewTitle) )
		printf("SetConsoleTitle failed (%d)\n", GetLastError());
   }


	plot.setColor(red);
	cout<<"              ____\n";
	cout<<"             / a_a\\\n";
	cout<<"             | | \"]\n";
	cout<<"         ____| '-\\___\n";
	cout<<"        /.----.___.-'\\\n";
	cout<<"       //        _    \\\n";
	cout<<"      //   .-. (";
	plot.setColor(yellow);
	cout<<"TEd";
	plot.setColor(red);
	cout<<") /|\n";
	cout<<"     |'|  /\\:  .--  / \\\n";
	cout<<"    // |-/  \\_/____/\\/~|\n";
	cout<<"   |/  \\ |  []_|_|_] \\ |\n";
	cout<<"   | \\  | \\ |___   _\\ ]_}\n";
	cout<<"   | |  '-' /   '.'  |\n";
	cout<<"   | |     /    /|:  |\n";
	cout<<"   | |     |   / |:  /\\\n";
	cout<<"   | |     /  /  |  /  \\\n";
	cout<<"   | |    |  /  /  |    \\\n";
	cout<<"   \\ |    |/\\/  |/|/\\    \\\n";
	cout<<"    \\|\\ |\\|  |  | / /\\/\\__\\\n";
	cout<<"     \\ \\| | /   | |__\n";
	cout<<"          / |   |____)\n";
	cout<<"          |_/\n\n";
	
	plot.setColor(white);
	cout<<"Welcome to TEd, the Tron Level Editor!\n\nCreated by:\nThomas Lee\nTrey Turley\nMarc Willis\n\nPress Enter to begin...";
	while(!KEYDOWN(VK_RETURN));
	cin.ignore(10000,'\n');
	while(running)
	{
		for(int i=0;i<80;i++)
		{
			for(int j=0;j<40;j++)
			{
				if(i==0||i==79||j==0||j==39)
				{
					map[i][j]=15;
				}else{
					map[i][j]=0;
				}
			}
		}
		playerData[0][0]=1;
		playerData[0][1]=1;
		playerData[0][2]=3;
		playerData[1][0]=78;
		playerData[1][1]=38;
		playerData[1][2]=1;
		playerData[2][0]=1;
		playerData[2][1]=38;
		playerData[2][2]=2;
		playerData[3][0]=78;
		playerData[3][1]=1;
		playerData[3][2]=4;
		inMenu=true;
		plot.clear();
		cout<<"MAIN MENU:\n\n1)   Create new map\n2)   Load map\nEsc) Quit";
		while(inMenu)
		{
			if(KEYDOWN(VK_KEY_1))
			{
				cout<<"\n\nYou selected \"Create new map\".  Press Enter to continue or F1 to return.";
				bool innerMenu=true;
				while(innerMenu)
				{
					if(KEYDOWN(VK_RETURN))
					{
						selection=1;
						inMenu=false;
						innerMenu=false;
					}
					if(KEYDOWN(VK_F1))
					{
						plot.clear();
						cout<<"MAIN MENU:\n\n1)   Create new map\n2)   Load map\nEsc) Quit";
						innerMenu=false;
					}
				}
			}
			if(KEYDOWN(VK_KEY_2))
			{
				cout<<"\n\nYou selected \"Load map\".  Press Enter to continue or F1 to return.";
				bool innerMenu=true;
				while(innerMenu)
				{
					if(KEYDOWN(VK_RETURN))
					{
						selection=2;
						inMenu=false;
						innerMenu=false;
					}
					if(KEYDOWN(VK_F1))
					{
						plot.clear();
						cout<<"MAIN MENU:\n\n1)   Create new map\n2)   Load map\nEsc) Quit";
						innerMenu=false;
					}
				}
			}
			if(KEYDOWN(VK_ESCAPE))
			{
				selection=3;
				running=false;
				inMenu=false;
			}
		}
		if(selection!=3)
		{
			cin.ignore(10000,'\n');
			plot.clear();
			if(selection==2)
			{
				cout<<"\nEnter the filename of the map you wish to load:\n";
				cin.getline(filename,1000);
				infile.open(filename);
				if(infile)
				{
					bool valid=true;
					for(int i=0;i<80&&valid;i++)
					{
						for(int j=0;j<40&&valid;j++)
						{
							if(!infile)
							{
								valid=false;
							}else{
								infile>>map[i][j];
							}
						}
					}
					for(int i=0;i<4&&valid;i++)
					{
						for(int j=0;j<3&&valid;j++)
						{
							if(!infile)
							{
								valid=false;
							}else{
								infile>>playerData[i][j];
							}
						}
					}
					if(!valid)
					{
						for(int i=0;i<80;i++)
						{
							for(int j=0;j<40;j++)
							{
								if(i==0||j==0||i==79||j==39){
									map[i][j]=white;
								}else{
									map[i][j]=0;
								}
							}
						}
						playerData[0][0]=1;
						playerData[0][1]=1;
						playerData[0][2]=3;
						playerData[1][0]=78;
						playerData[1][1]=38;
						playerData[1][2]=1;
						playerData[2][0]=1;
						playerData[2][1]=38;
						playerData[2][2]=3;
						playerData[3][0]=78;
						playerData[3][1]=1;
						playerData[3][2]=4;
					}
				}
				infile.close();
				outfile.open(filename);
			}
			if(selection==1)
			{
				do{
					cout<<"\nEnter the filename you wish to save the file to:\n";
					cin.getline(filename,1000);
					outfile.open(filename);
					if(!outfile)
					{
						outfile.close();
						cout<<"Error opening output file, try another filename.\n\n";
					}
				}while(!outfile);
			}
			plot.clear();
			for(int i=0;i<80;i++)
			{
				for(int j=0;j<40;j++)
				{
					if(map[i][j]!=0)
					{
						plot.plotTrail(i,j,map[i][j],SQUARE);
					}
				}
			}
			for(int i=0;i<4;i++)
			{
				plot.plotTrail(playerData[i][0],playerData[i][1],playerColor(i+1),dirToChar(playerData[i][2]));
			}
			if(map[0][0]!=white)
			{
				plot.plotTrail(0,0,map[0][0]*16+white,CURSOR);
			}else{
				plot.plotTrail(0,0,white*16,CURSOR);
			}

			plot.move(0,40);
			plot.setColor(white);
			cout<<"Use the arrows to move your cursor.\n";
			cout<<"Use QWERTYUI and ASDFGHJK to place colors (Q is delete).\n";
			cout<<"To reassign a player's start position, press the number of the";
			cout<<" player, then the\n   direction you want them to face.\n";
			cout<<"Press F1 to save and return to the main menu, or ESC to save and quit.";
			cursorX=0;
			cursorY=0;
			
			bool editing=true;
			while(editing)
			{
				if(KEYDOWN(VK_ESCAPE))
				{
					editing=false;
					running=false;
				}
				if(KEYDOWN(VK_F1))
				{
					editing=false;
				}
				if(KEYDOWN(VK_UP)&&cursorY>0)
				{
					plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY],SQUARE);
					for(int i=0;i<4;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							plot.plotTrail(playerData[i][0],playerData[i][1],playerColor(i+1),dirToChar(playerData[i][2]));
						}
					}
					cursorY--;
					if(map[cursorX][cursorY]==white)
					{
						plot.plotTrail(cursorX,cursorY,0xF0,CURSOR);
					}else{
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_DOWN)&&cursorY<39)
				{
					plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY],SQUARE);
					for(int i=0;i<4;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							plot.plotTrail(playerData[i][0],playerData[i][1],playerColor(i+1),dirToChar(playerData[i][2]));
						}
					}
					cursorY++;
					if(map[cursorX][cursorY]==white)
					{
						plot.plotTrail(cursorX,cursorY,0xF0,CURSOR);
					}else{
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				Sleep(50);
				if(KEYDOWN(VK_LEFT)&&cursorX>0)
				{
					plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY],SQUARE);
					for(int i=0;i<4;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							plot.plotTrail(playerData[i][0],playerData[i][1],playerColor(i+1),dirToChar(playerData[i][2]));
						}
					}
					cursorX--;
					if(map[cursorX][cursorY]==white)
					{
						plot.plotTrail(cursorX,cursorY,0xF0,CURSOR);
					}else{
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_RIGHT)&&cursorX<79)
				{
					plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY],SQUARE);
					for(int i=0;i<4;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							plot.plotTrail(playerData[i][0],playerData[i][1],playerColor(i+1),dirToChar(playerData[i][2]));
						}
					}
					cursorX++;
					if(map[cursorX][cursorY]==white)
					{
						plot.plotTrail(cursorX,cursorY,0xF0,CURSOR);
					}else{
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_Q)&&cursorX!=0&&cursorY!=0&&cursorX!=79&&cursorY!=39)
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=black;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_W))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=darkblue;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_E))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=darkgreen;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_R))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=darkcyan;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_T))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=darkred;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_Y))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=purple;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_U))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=darkyellow;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_I))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=lightgrey;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_A))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=grey;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_S))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=blue;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_D))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=green;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_F))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=cyan;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_G))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=red;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_H))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=magenta;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_J))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=yellow;
						plot.plotTrail(cursorX,cursorY,map[cursorX][cursorY]*16+white,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_K))
				{
					bool okay=true;
					for(int i=0;i<4&&okay;i++)
					{
						if(playerData[i][0]==cursorX&&playerData[i][1]==cursorY)
						{
							okay=false;
						}
					}
					if(okay)
					{
						map[cursorX][cursorY]=white;
						plot.plotTrail(cursorX,cursorY,white*16,CURSOR);
					}
				}
				if(KEYDOWN(VK_KEY_1)&&map[cursorX][cursorY]==0)
				{
					plot.plotTrail(playerData[0][0],playerData[0][1],black,SQUARE);
					plot.plotTrail(cursorX,cursorY,white,233);
					inMenu=true;
					playerData[0][0]=cursorX;
					playerData[0][1]=cursorY;
					while(inMenu)
					{
						if(KEYDOWN(VK_UP))
						{
							inMenu=false;
							playerData[0][2]=2;
						}
						if(KEYDOWN(VK_LEFT))
						{
							inMenu=false;
							playerData[0][2]=1;
						}
						if(KEYDOWN(VK_RIGHT))
						{
							inMenu=false;
							playerData[0][2]=3;
						}
						if(KEYDOWN(VK_DOWN))
						{
							inMenu=false;
							playerData[0][2]=4;
						}
					}
					plot.plotTrail(cursorX,cursorY,white,CURSOR);
				}
				if(KEYDOWN(VK_KEY_2)&&map[cursorX][cursorY]==0)
				{
					plot.plotTrail(playerData[1][0],playerData[1][1],black,SQUARE);
					plot.plotTrail(cursorX,cursorY,white,233);
					inMenu=true;
					playerData[1][0]=cursorX;
					playerData[1][1]=cursorY;
					while(inMenu)
					{
						if(KEYDOWN(VK_UP))
						{
							inMenu=false;
							playerData[1][2]=2;
						}
						if(KEYDOWN(VK_LEFT))
						{
							inMenu=false;
							playerData[1][2]=1;
						}
						if(KEYDOWN(VK_RIGHT))
						{
							inMenu=false;
							playerData[1][2]=3;
						}
						if(KEYDOWN(VK_DOWN))
						{
							inMenu=false;
							playerData[1][2]=4;
						}
					}
					plot.plotTrail(cursorX,cursorY,white,CURSOR);
				}
				if(KEYDOWN(VK_KEY_3)&&map[cursorX][cursorY]==0)
				{
					plot.plotTrail(playerData[2][0],playerData[2][1],black,SQUARE);
					plot.plotTrail(cursorX,cursorY,white,233);
					inMenu=true;
					playerData[2][0]=cursorX;
					playerData[2][1]=cursorY;
					while(inMenu)
					{
						if(KEYDOWN(VK_UP))
						{
							inMenu=false;
							playerData[2][2]=2;
						}
						if(KEYDOWN(VK_LEFT))
						{
							inMenu=false;
							playerData[2][2]=1;
						}
						if(KEYDOWN(VK_RIGHT))
						{
							inMenu=false;
							playerData[2][2]=3;
						}
						if(KEYDOWN(VK_DOWN))
						{
							inMenu=false;
							playerData[2][2]=4;
						}
					}
					plot.plotTrail(cursorX,cursorY,white,CURSOR);
				}
				if(KEYDOWN(VK_KEY_4)&&map[cursorX][cursorY]==0)
				{
					plot.plotTrail(playerData[3][0],playerData[3][1],black,SQUARE);
					plot.plotTrail(cursorX,cursorY,white,233);
					inMenu=true;
					playerData[3][0]=cursorX;
					playerData[3][1]=cursorY;
					while(inMenu)
					{
						if(KEYDOWN(VK_UP))
						{
							inMenu=false;
							playerData[3][2]=2;
						}
						if(KEYDOWN(VK_LEFT))
						{
							inMenu=false;
							playerData[3][2]=1;
						}
						if(KEYDOWN(VK_RIGHT))
						{
							inMenu=false;
							playerData[3][2]=3;
						}
						if(KEYDOWN(VK_DOWN))
						{
							inMenu=false;
							playerData[3][2]=4;
						}
					}
					plot.plotTrail(cursorX,cursorY,white,CURSOR);
				}
			}
			for(int i=0;i<80;i++)
			{
				for(int j=0;j<40;j++)
				{
					outfile<<map[i][j]<<" ";
				}
			}
			for(int i=0;i<4;i++)
			{
				for(int j=0;j<3;j++)
				{
					outfile<<playerData[i][j]<<" ";
				}
			}
			outfile.close();
		}
	}
	plot.setColor(white);
	plot.clear();
	cout<<"Thanks for using TEd!\n";
	return 0;
}